classdef MultiLabelGeometricF1Measure ...
        < MultiLabelMetric
    %MULTILABELGEOMETRICF1MEASURE Summary of this class goes here
    %   Detailed explanation goes here
    
    properties
    end
    
    methods
        function [ this ] = MultiLabelGeometricF1Measure( name )
            this.setName('geof1')
        end
    end
    
    methods
    end
    
    methods ( Static = true )
        function [ result, algmean ] = calc( Y, Y_hat, Y_out )
            nLabel = size(Y, 2);
            z_result = zeros(1, nLabel);
            
            for iLabel = 1:nLabel
                z_result(iLabel) = calcF1Measure(Y(:, iLabel), Y_hat(:, iLabel));
            end
            
            result = geomean(z_result);
            algmean = mean(z_result);
        end
    end
    
end

function [ result ] =  calcF1Measure( Y, Y_hat )

nTP = nnz(Y ==  1 & Y_hat ==  1);
nFP = nnz(Y == -1 & Y_hat ==  1);
nFN = nnz(Y ==  1 & Y_hat == -1);

if nTP == 0 && nFP == 0
    precision = 1;
else
    precision = nTP/(nTP + nFP);
end

if nTP == 0 && nFN == 0
    recall = 1;
else
    recall = nTP/(nTP + nFN);
end

if all(Y == Y_hat)
    precision = 1;
    recall = 1;
end

if precision == 0 && recall == 0
    result = 0;
else
    result = 2*precision*recall/(precision + recall);
end

end
